<?php

namespace addons\mental\controller;

use addons\mental\model\Order as orderModel;
use app\admin\model\Exchangecode;
use app\admin\model\xlzxinfo\Xlzxinfo;
use app\admin\model\xlzxinfo\Package;
use app\admin\model\consult\Order;
use app\common\model\WxTui;
use app\common\model\YunXin;
use app\common\model\YunxinCalllog;
use think\Config;
use think\Db;
use think\Exception;
use think\Log;
use think\Queue;
use function GuzzleHttp\Psr7\uri_for;

/*
 * 咨询
 * */
class Consult extends Base
{
    protected $noNeedLogin = ['twoWayCallback','twoWayCall'];

    /**
     *
     * 咨询下单
     */
    public function create()
    {
        $type = $this->request->post('type',0);//1立即咨询 2预约咨询
        $xlzxinfo_id = $this->request->post('xlzxinfo_id',0);
        $consult_type = $this->request->post('consult_type',0);//1文字 2语音
        $minutes = $this->request->post('minutes',0); //服务时间
        $start_time = $this->request->post('start_time','');
        $msg = $this->request->post('msg','');
        $phone = $this->request->post('phone','');
        $wechat = $this->request->post('wechat','');
        $qq = $this->request->post('qq','');
    
        // 套餐
        $is_package = $this->request->post('is_package',0);
        if($is_package>0){
            $package = Package::get($is_package);
            if(!empty($package)){
                $type = 1;
                $xlzxinfo_id = $package['zxs_id'];
                $consult_type = $package['typeId'];
                $minutes = $package['package_duration'] * 60;
                $price = $package['package_price'];
            }
        }

        if (!in_array($type,[1,2])){
            $this->error('咨询类型有误');
        }
        if (!in_array($consult_type,[1,2])){
            $this->error('咨询类型有误');
        }
        $xlzxinfo = Xlzxinfo::where(['id'=>$xlzxinfo_id,'status'=>1])->find();
        if (!$xlzxinfo){
            $this->error('咨询师不存在');
        }
        if ($xlzxinfo['user_id']==$this->auth->id){
            $this->error('不能给自己下单');
        }
//        $order = Order::where(['pay_status'=>'paid','status'=>2,'xlzxinfo_id'=>$xlzxinfo_id])->find();
//        if ($order){
//            $this->error('咨询师正在咨询中请在预约咨询下单');
//        }
        if ($type==2){
            $end_time_int = strtotime($start_time)+($minutes*60);
            $end_time = datetime($end_time_int);
            $order = Order::where(['pay_status'=>'paid','status'=>1,'type'=>2,'xlzxinfo_id'=>$xlzxinfo_id])->where('start_time','>=',$start_time)->where('end_time','<=',$start_time)->find();
            if ($order){
                $this->error('咨询师已有预约单,请选择其他时间');
            }
        }else{
            $order2 = Order::where(['pay_status'=>'paid','xlzxinfo_id'=>$xlzxinfo_id,'consult_type'=>$consult_type,'user_id'=>$this->auth->id])->where(['effective_time'=>['>',time()]])->whereIn('status',[2])->find();
            if ($order2){
                $this->error('咨询师正在服务,请预约下单');
            }
            //判断用户和咨询师是否有未完成的订单
            $order3 = Order::where(['pay_status'=>'paid','xlzxinfo_id'=>$xlzxinfo_id,'user_id'=>$this->auth->id])->where(['effective_time'=>['>',time()]])->order('createtime desc')->find();
            if ($order3 && $order3['effective_time']<time()){
                if($order3['status']==2 && empty($order3['server_end_time'])){
                    $this->error('有未完成的咨询,不可重复下单');
                }
            }
        }
        
        // if (!in_array($minutes,[15,30,60])){
        //     $this->error('规格有误');
        // }
        if ($consult_type==1 && $is_package==0){//1文字
            $file = "chat_price_15";
            $price = bcdiv($minutes,15) * $xlzxinfo["$file"];
        }
        if ($consult_type==2 && $is_package==0){//2语音
            $file = "call_price_15";
            $price = bcdiv($minutes,15) * $xlzxinfo["$file"];
        }
        // if ($consult_type==1){//1文字
        //     // $file = "chat_price_".$minutes;
        //     // if ($xlzxinfo["$file"]<0){
        //     //     $this->error('咨询师价格未更新');
        //     // }
        //     $price = $xlzxinfo["$file"];
        // }
        // if ($consult_type==2){//2语音
        //     // $file = "call_price_".$minutes;
        //     // if ($xlzxinfo["$file"]<0){
        //     //     $this->error('咨询师价格未更新');
        //     // }
        //     $price = $xlzxinfo["$file"];
        // }
        // if ($type==2){
        //     if (!$start_time){
        //         $this->error('请选择预约时间');
        //     }
        //     //预约订单
        //     $start_time_int = strtotime($start_time)+($minutes*60);
        //     $end_time = datetime($start_time_int);
        // }

        // //佣金
        // $commission_rate = Config::get('site.commission_rate');
        // $commission_price = bcMath($price,$commission_rate/100,'*',4);
        $order_sn = buildNo('C');

        //生成订单
        // 启动事务
        Db::startTrans();
        try{
            $data = [
                'id'=>date("Ymdhis") . sprintf("%08d", $this->auth->id) . mt_rand(1000, 9999),
                'user_id'=>$this->auth->id,
                'xlzxinfo_id'=>$xlzxinfo_id,
                'type'=>$type,
                'price'=>$price,
                'consult_type'=>$consult_type,
                'minutes'=>$minutes,
                'start_time'=>$type==2?$start_time:null,
                'end_time'=>$type==2?$end_time:null,
                'order_sn'=>$order_sn,
                'commission_price'=>0,
                'commission_rate'=>0,
                'msg'=>$msg,
                'phone'=>$phone,
                'wechat'=>$wechat,
                'qq'=>$qq,
                'is_package'=>$is_package
            ];
            $order = Order::create($data);

            // 提交事务
            Db::commit();
        } catch (\Exception $e) {
            // 回滚事务
            Db::rollback();
            $this->error('下单失败:'.$e->getMessage());
        }

        $this->success('下单成功',$order);
    }

    /*
     * 支付
     * */
    public function pay()
    {
        $order_id = $this->request->post('order_id');
        $paytype = $this->request->param('paytype', 'wechat');
        $code = $this->request->param('code', '');
        if (!$order_id) {
            $this->error(__('Invalid parameters'));
        }
//        //给老师发送公众号模板消息
//        \addons\mental\model\WxUser::push_template($order_id);
//        die;
        $order = Order::where(['user_id'=>$this->auth->id,'pay_status'=>'created','id'=>$order_id])->find();
        if (!$order){
            $this->error('订单不存在');
        }
        if ($order['consult_type']==1){
            $type = 3;
        }elseif ($order['consult_type']==2){
            $type = 2;
        }
        if ($paytype=='code'){
            if (!$code){
                $this->error('请输入兑换码');
            }
            $code_exist = Exchangecode::where(['code'=>$code,'status'=>0,'type'=>$type])->find();
            if (!$code_exist){
                $this->error('兑换码不存在');
            }
            if($code_exist['nullify']==0){
                $this->error('该兑换码已作废');
            }
            // if ($code_exist['zx_minutes']<$order['minutes']){
            //     $this->error('兑换码可用时间小于订单选择时间');
            // }
            if ($code_exist['zx_minutes']!=$order['minutes']){
                $this->error('兑换码可用时间('.$code_exist['zx_minutes'].')和订单选择时间('.$order['minutes'].')不一致');
            }
            if ($code_exist['zx_xlzxinfoid']!=$order['xlzxinfo_id']){
                $this->error('兑换码所属咨询师和下单咨询师不一致');
            }
            // 启动事务
            Db::startTrans();
            try {
                //更新兑换卡
                $code_exist->zx_xlzxinfoid = $order['xlzxinfo_id'];
                $code_exist->user_id = $this->auth->id;
                $code_exist->order_id = $order_id;
                $code_exist->status = 1;
                $code_exist->save();

                $now = datetime(time());
                // 订单有效期  3天
                if($order['is_package']==0){
                    $day_time = Config::get('site.effective_day') * 24 * 60 * 60;
                }
                // 套餐单独的有效期  3个月
                if($order['is_package']>0){
                    $package_info = Package::get($order['is_package']);
                    $day_time = $package_info['package_expiration_month']* 30 * 24 * 60 * 60;
                }
                $effective_time = strtotime($now)+$day_time;

                //更新订单
                $order->pay_status = 'paid';
                $order->pay_time = $now;
                $order->effective_time = $effective_time;
                $order->pay_type = 'code';
//                $order->server_start_time = $now;
                $order->save();
                // 提交事务
                Db::commit();
            } catch (\Exception $e) {
                // 回滚事务
                Db::rollback();
                Log::info("兑换测试失败:order_id=$order_id;errog=".$e->getMessage());
                $this->error('兑换失败');
            }

            //预约订单给老师发送公众号模板消息
            \addons\mental\model\WxUser::push_template_order($order_id);

             //调用im,给小程序发送消息，支付完新订单。
             $data = \app\common\library\Ims::send_business_notification_order($order_id);
//            if ($order['type']==2){
//                $xlzxinfo = Xlzxinfo::where(['id'=>$order['xlzxinfo_id']])->find();
//                $touser = \app\common\model\User::where('id',$xlzxinfo['user_id'])->find();
//                $response = WxTui::sendMessage2($touser['openid'],$order['id'],$order['start_time']);
//                Log::info($response);
//            }
        }else{
            try {

                $paytype = 'wechat';
                $method = 'miniapp';
                $attach = 'consult';//订单类型 mental=评测 video=视频 consult=沟通
                $url = $this->request->param('url', '', 'trim'); //公众号授权回调url 或 h5支付回调url
                $openid = \app\admin\model\User::where(['id'=>$this->auth->id])->value('openid');

                $result = orderModel::pay($this->auth->id, $order_id, $order->price, $paytype, $method, $url, $openid, $attach);
                if (!is_array($result)) {
                    $this->success(__('Operation completed'), $result);
                } else {
                    $this->error(__('Operation failed'), $result['data'], 2); //判断公众号授权
                }
            } catch (Exception $e) {
                $this->error($e->getMessage());
            }
        }


        $this->success('发起支付');
    }

    /*
     * 开始服务
     * */
    public function start_server()
    {
        $order_id = $this->request->post('order_id');
        $xlzxinfo = Xlzxinfo::where(['user_id'=>$this->auth->id])->find();
        $order = Order::where(['xlzxinfo_id'=>$xlzxinfo['id'],'pay_status'=>'paid','id'=>$order_id])->find();
        if (!$order){
            $this->error('订单不存在');
        }
        if ($order['consult_type']!=1){
            $this->error('不是文字咨询类型');
        }
        if ($order['status']==2){
            $this->error('服务已开始');
        }
        if ($order['status']==3){
            $this->error('服务已完成');
        }
        if ($order['status']==5){
            $this->error('订单已关闭');
        }
        $other_order = Order::where(['xlzxinfo_id'=>$xlzxinfo['id'],'pay_status'=>'paid','status'=>2,'consult_type'=>1])->where(['effective_time'=>['>',time()]])->where('id','<>',$order_id)->find();
        if ($other_order){
            $this->error('有订单正在服务中');
        }
        //更新开始服务时间
        $order->server_start_time = datetime(time());
        $order->status = 2;
        $order->save();

        $job = 'app\job\ConsultJob'; // 当前任务由哪个类负责处理
        $queueName = 'consult_job_queue';  // 当前队列归属的队列名称
        $second = $order['minutes'] * 60;
        Log::info('开始服务延迟队列时间1:'.$second);
//        $second = 10 * 60;
//        Log::info('开始服务延迟队列时间2:'.$second);
        $res = Queue::later($second,$job, $order['id'], $queueName);   // 订单到期

        $second2 = $second - 300;//剩余5分钟提醒
        $res = Queue::later($second2,'app\job\XufeiJob', $order['id'], 'xufei_job_queue');   // 订单续费提醒
//        Log::log('消息投递:'.$res);
        $this->success('请求成功');
    }

    /*
     * 用户与咨询师是否有沟通订单
     * */
    public function user_xlzx_order()
    {
        $xlzxinfo_id = $this->request->get('xlzxinfo_id',0);
        $order = Order::where(['user_id'=>$this->auth->id,'pay_status'=>'paid','xlzxinfo_id'=>$xlzxinfo_id])->whereIn('status',[1,2])->where(['effective_time'=>['>',time()]])->order('createtime','desc')->find();
        if (!$order){
            $this->error('还未下单');
        }
        //语音咨询文案
        $order['voice_text'] = config('site.voice_text');
        $this->success('请求成功',$order);
    }

    /*
     * 咨询师与用户是否有沟通订单
     * */
    public function zxs_xlzx_order()
    {
        $user_id = $this->request->get('user_id',0);
        $xlzxinfo = Xlzxinfo::where(['user_id'=>$this->auth->id])->find();
        $order = Order::where(['user_id'=>$user_id,'pay_status'=>'paid','xlzxinfo_id'=>$xlzxinfo['id']])->whereIn('status',[1,2])->where(['effective_time'=>['>',time()]])->order('createtime','desc')->find();
        if (!$order){
            $this->error('还未下单');
        }
        //语音咨询文案
        $order['voice_text'] = config('site.voice_text');
        $this->success('请求成功',$order);
    }

    /*
     * 用户订单列表
     * */
    public function user_order_list()
    {
        $list = Order::with(['xlzxinfo'])->where(['fa_consult_order.user_id'=>$this->auth->id,'pay_status'=>'paid'])->order('fa_consult_order.createtime','desc')->paginate();

        foreach ($list as $key => $value) {
            if($value['effective_time']<time()){
                $value['status'] = 4;
            }
        }
        $this->success('请求成功',$list);
    }

    /*
     * 咨询师咨询订单列表
     * */
    public function xlzx_order_list()
    {
        $xlzxinfo = Xlzxinfo::where(['user_id'=>$this->auth->id])->find();
        if (!$xlzxinfo){
            $this->error('还不是咨询师');
        }

        $list = Order::with(['user'])->where(['fa_consult_order.xlzxinfo_id'=>$xlzxinfo['id'],'fa_consult_order.pay_status'=>'paid'])->order('createtime','desc')->paginate();
        foreach ($list as $key => $value) {
            if($value['effective_time']<time()){
                $value['status'] = 4;
            }
            if(!empty($value['user'])){
                $value['user']->avatar = empty($value['user']->avatar)? letter_avatar($value['user']->nickname):$value['user']->avatar;
            }
        }

        $this->success('请求成功',$list);
    }

    /**
     * 订单详情
     * @return void
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function  detail()
    {
        $order_id = $this->request->param('order_id');
        if (!$order_id) {
            $this->error(__('Invalid parameters'));
        }
        //user
        $order = Order::with(['xlzxinfo'])
            ->where(['fa_consult_order.id'=>$order_id])
            ->find();
        $order['user_nickname'] = Db::name('user')->where(['id'=>$order['user_id']])->value('nickname');
        $order['user_avatar'] = Db::name('user')->where(['id'=>$order['user_id']])->value('avatar');
        if($order['pay_type']=='code' && $order['exchange_price']!='0.00'){//兑换码订单
            $per_minute_price = bcdiv($order['exchange_price'],$order['minutes'],2);
            if($order['consult_type']==1){ //文字费用
                $order['order_cost'] = $order['exchange_price'];
            }
            if($order['consult_type']==2){ //语音费用
                $fen = ceil(bcdiv($order['talk_duration'],60));
                $order['order_cost'] = bcmul($per_minute_price,$fen);
            }
        }else{ //普通正常订单
            $per_minute_price = bcdiv($order['price'],$order['minutes'],2);
            if($order['consult_type']==1){ //文字费用
                $order['order_cost'] = $order['price'];
            }
            if($order['consult_type']==2){ //语音费用
                $fen = ceil(bcdiv($order['talk_duration'],60));
                $order['order_cost'] = bcmul($per_minute_price,$fen);
            }
        }
        $order['per_minute_price'] = $per_minute_price;
        $this->success(__('Operation completed'), $order);
    }

    public function refund_list()
    {
        $user_id = $this->auth->id;
        $refund_list = Db::name('refund_order')->where(['user_id'=>$user_id])->order('create_time desc')->select();
        foreach ($refund_list as $key => $value) {
            $order = Order::where(['id'=>$value['order_id']])->find();
            $miao = Db::name('yunxin_calllog')->where(['id'=>$value['order_id']])->sum('duration');
            $danjia = bcdiv($order['price'],$order['minutes'],2);
            if($miao>0){
                $refund_price = ($order['minutes']-ceil($miao / 60))*$danjia;
            }else{
                $refund_price = $order['price'];
            }
            $refund_list[$key]['price'] = $order['price'];
            $refund_list[$key]['pay_time'] = $order['pay_time'];
            $refund_list[$key]['order_sn'] = $order['order_sn'];
            $refund_list[$key]['minutes'] = $order['minutes'];
            $refund_list[$key]['used_minutes'] = ceil($miao / 60);
            $refund_list[$key]['refund_price'] = $refund_price;
        }
        $this->success('查询成功', $refund_list);
    }
    /**
     *
     * @return void
     */
    public function order_detail()
    {
        $order_id = $this->request->param('order_id');
        if (!$order_id) {
            $this->error(__('Invalid parameters'));
        }
        //user
        $order = Order::where(['id'=>$order_id])->find();

        $miao = Db::name('yunxin_calllog')->where(['id'=>$order['id']])->sum('duration');
        $danjia = bcdiv($order['price'],$order['minutes'],2);

        $order['used_minutes'] = $miao>0?ceil($miao / 60):0;
        //退款金额
        if($miao>0){
            $refund_price = ($order['minutes']-ceil($miao / 60))*$danjia;
        }else{
            $refund_price = $order['price'];
        }
        $order['refund_price'] = $refund_price??0;

        $refund = Db::name('refund_order')->where(['order_id'=>$order['id']])->find();

        $order['refund_status'] = $refund['refund_status'];
        //退款原因
        $order['refund_reason'] = $refund['refund_reason']??'';
        //退款备注
        $order['refund_notes'] = $refund['refund_notes']??'';

        $this->success(__('查询成功'), $order);
    }

    public function refund_detail()
    {
        $refund_id = $this->request->param('refund_id');
        if (!$refund_id) {
            $this->error(__('Invalid parameters'));
        }

        $refund = Db::name('refund_order')->where(['id'=>$refund_id])->find();

        //user
        $order = Order::where(['id'=>$refund['order_id']])->find();

        $miao = Db::name('yunxin_calllog')->where(['id'=>$order['id']])->sum('duration');
        $danjia = bcdiv($order['price'],$order['minutes'],2);

        $order['used_minutes'] = $miao>0?ceil($miao / 60):0;
        //退款金额
        if($miao>0){
            $refund_price = ($order['minutes']-ceil($miao / 60))*$danjia;
        }else{
            $refund_price = $order['price'];
        }
        $order['refund_price'] = $refund_price??0;
        $order['refund_status'] = $refund['refund_status'];
        //退款原因
        $order['refund_reason'] = $refund['refund_reason']??'';
        //退款备注
        $order['refund_notes'] = $refund['refund_notes']??'';

        $this->success(__('查询成功'), $order);
    }

    /**
     * 申请退款接口
     * @return void
     */
    public function  refund(){
        $order_id = $this->request->param('order_id');
        $refund_reason = $this->request->param('refund_reason');
        $refund_notes = $this->request->param('refund_notes');
        if (!$order_id) {
            $this->error(__('Invalid parameters'));
        }
        $order = Order::where(['id'=>$order_id])->find();
        if($order['is_refund']==1){
           if($order['refund_status']==1){
               $this->error(__('订单已申请退款中不可重复申请'));
           }
            if($order['refund_status']==3){
                $this->error(__('订单退款已完成'));
            }
        }
        $update =  [
           'is_refund'=>1,
           'refund_status'=>1
        ];
        $add = [
            'user_id'=>$this->auth->id,
            'order_id'=>$order_id,
            'refund_reason'=>$refund_reason,
            'refund_notes'=>$refund_notes,
            'refund_status'=>1,
            'create_time'=>time(),
            'update_time'=>time(),
        ];
        $res = $order = Order::where(['id'=>$order_id])->update($update);
        if($res){
            Db::name('refund_order')->insert($add);
            $this->success('申请退款成功，待后台审核成功后，1-5个工作日返回付款账户！');
        }else{
            $this->error('退款失败');
        }
    }
    /*
     * 云信双向呼叫
     * */
    public function twoWayCall()
    {
        $order_id = $this->request->param('order_id');
        Log::info('呼叫进来了');
        Log::info($order_id);
        if (!$order_id) {
            $this->error(__('Invalid parameters'));
        }
        $order = Order::with(['user','xlzxinfo'])
            // ->where('user_id', $this->auth->id)
            ->where('order.id', $order_id)
            ->find();

        if (!$order){
            $this->error('订单不存在');
        }
        if ($order['pay_status']!='paid'){
            $this->error('订单未支付');
        }
        if($order['effective_time']<time()){
            $this->error('订单已过有效期');
        }
        if($order['status']==3){
            $this->error('订单已完成');
        }
        if($order['status']==5){
            $this->error('订单已关闭');
        }
        // 订单通话分钟
        $minutes = $order['minutes'];
        // 已使用 通话分钟
        $use_minutes = $order['talk_duration'];
        $fminutes = $minutes-$use_minutes;
        if($fminutes<=0){
            $this->error('订单咨询时间已结束');
        }
        $response = YunXin::twoWayCall($order['user']['mobile'],$order['xlzxinfo']['phone'],$fminutes);
        Log::info($order['user']['mobile']);
        Log::info('####');
        Log::info($order['xlzxinfo']['phone']);
        if ($response['result']!='000000'){
            Log::info('呼叫失败');
            Log::info($response);
            $this->error('呼叫失败');
        }
        //生成呼叫记录
        $yunxin_log = [
            'callId'=>$response['callId'],
            'order_id'=>$order_id,
            'user_id'=>$order['user']['id'],
            'xlzxinfo_id'=>$order['xlzxinfo']['id'],
            'callerNumber'=>$order['user']['mobile'],
            'calleeNumber'=>$order['xlzxinfo']['phone'],
            'createtime'=>time()
        ];
        $YunxinCalllogModel = new YunxinCalllog();
        $YunxinCalllogModel->save($yunxin_log);
        $this->success('请求成功',$response);
    }


    /*
     * 云信双向呼叫-结果推送回调
     * */
    public function twoWayCallback()
    {
        Log::info('云信双向呼叫结果推送回调');
        Log::info('param----start');
        $param = $this->request->param();
        // Db::name('yunxin_calllog')->where('id',16)->update(['logs'=>json_encode($param)]);
        Log::info($param);
        if (empty($param)){
            $this->error();
        }
        Log::info('param----end');
        // halt($param);
        $response = YunXin::twoWayCallback($param);
        $this->success('请求成功',$response);
    }
}
